﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using PulseLibrary;
using PulseLibrary.GUIControls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using PulsePrototype.PulseManagers;
using Microsoft.Xna.Framework.Graphics;

namespace PulsePrototype.GameStates
{
    public class GamePlayScreen : BaseGameState
    {
        Label exitLabel;
        private GraphicsDeviceManager graphics;
        private Dictionary<String, BaseManager> managers;

        public GraphicsDeviceManager Graphics
        {
            get { return this.graphics; }
            set { this.graphics = value; }
        }

        public Dictionary<String, BaseManager> Managers
        {
            get { return this.managers; }
        }

        public GamePlayScreen(Game1 game, GameStateManager manager)
            : base(game, manager)
        {
            this.graphics = GameRef.Graphics;
            this.managers = new Dictionary<string, BaseManager>(); 
        }

        public override void Initialize()
        {
            // Huge problem: SceneManager can't create PhysicsComponents without a PhysicsManager existing.
            // PhysicsManager's Draw method can't work without a SceneManager exisitng.
            // There's a timing race going on that's barely holding together.
            PhysicsManager physicsManager = new PhysicsManager(GameRef);
            SceneManager sceneManager = new SceneManager(GameRef);
            RenderManager renderManager = new RenderManager(GameRef);
            //AddManager(sceneManager);
            base.Initialize();
        }

        public void AddManager(BaseManager manager)
        {
            BaseManager checkManager = null;
            if (managers.TryGetValue(manager.Name, out checkManager))
            {
                return;
                //throw new Exception("Manager type " + manager.Name + " already exists within the game engine");
            }

            managers.Add(manager.Name, manager);
        }

        public BaseManager GetManager(String managerName)
        {
            BaseManager manager = null;
            if (!managers.TryGetValue(managerName, out manager))
            {
                // Manager wasn't found
            }

            return manager;
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            exitLabel = new Label();

            exitLabel.Position = new Vector2(0, 0);
            exitLabel.Text = "Press \"esc\" to close the game." +
            "\nPress Backspace to return to the Menu" +
            "\nPress Enter to return to the Title Screen." +
            "\nPress F11 to toggle game screen text." +
            "\nPress F10 for physics debug mode." +
            "\nPress F9 for texture debug mode.";
            exitLabel.Color = Color.White;

            controlManager.Add(exitLabel);

            foreach (KeyValuePair<String, BaseManager> pair in managers)
            {
                (pair.Value).LoadContent();
            }

        }

        protected override void UnloadContent()
        {
            base.UnloadContent();
            foreach (KeyValuePair<String, BaseManager> pair in managers)
            {
                (pair.Value).UnloadContent();
            }
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            if (InputManager.KeyReleased(Keys.Escape))
                Game.Exit();
            else if (InputManager.KeyReleased(Keys.Back))
                stateManager.PopState();
            else if (InputManager.KeyReleased(Keys.Enter))
                stateManager.ChangeState(GameRef.TitleScreen1);

            if (InputManager.KeyReleased(Keys.F11))
            {
                DebugSettings.GameDisplayText = !DebugSettings.GameDisplayText;
            }
            if (InputManager.KeyReleased(Keys.F10))
            {
                DebugSettings.PhysicsDebug= !DebugSettings.PhysicsDebug;
            }
            if (InputManager.KeyReleased(Keys.F9))
            {
                DebugSettings.RenderDebug = !DebugSettings.RenderDebug;
            }    

            foreach (KeyValuePair<String, BaseManager> pair in managers)
            {
                (pair.Value).Update(gameTime);
            }

        }

        public override void Draw(GameTime gameTime)
        {
            foreach (KeyValuePair<String, BaseManager> pair in managers)
            {
                (pair.Value).Draw(gameTime);
            }

            // Cornflower Blue = R:100 G:149 B:237 A: 255

            if (DebugSettings.GameDisplayText)
            {
                GameRef.SpriteBatch.Begin();

                base.Draw(gameTime);
                controlManager.Draw(GameRef.SpriteBatch);

                GameRef.SpriteBatch.End();
            }
            
        }
    }
}
